/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.stateless;

import entity.Capacity;
import entity.PlannedMonthlyDemand;
import java.util.Calendar;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import session.stateless.MRP.SaleForecast.SaleForecastBeanLocal;

/**
 *
 * @author zhozho
 */
@Stateless
public class PlannedMonthlyDemandBean implements PlannedMonthlyDemandBeanLocal {

    @PersistenceContext 
    private EntityManager em;
    @EJB
    SaleForecastBeanLocal saleForecastBeanLocal;
    
    private Capacity capacity = new Capacity();
    private String[] monthNameList = {"January", "February",
                          "March", "April", "May", "June", "July",
                          "August", "September", "October", "November",
                          "December"};
    
    public PlannedMonthlyDemand createPlannedMonthlyDemand(String month, Long productionPlan, Long inventory)
    {
        PlannedMonthlyDemand plannedMonthlyDemand = new PlannedMonthlyDemand();
        plannedMonthlyDemand.setMonthName(month);
        plannedMonthlyDemand.setProductionPlan(productionPlan);
        plannedMonthlyDemand.setInventory(inventory);
        plannedMonthlyDemand.setWorkingHours(0);
        plannedMonthlyDemand.setOvertimeHours(0);
        Long noWorkingDays = new Long(getWorkingDaysByMonth(month));
        plannedMonthlyDemand.setNumberOfWorkingDays(noWorkingDays);
        plannedMonthlyDemand.setNutriCapacity(capacity.getCapacityPerHrInCase_Nutri(), noWorkingDays);
        plannedMonthlyDemand.setPremiumCapacity(capacity.getCapacityPerHrInCase_Power(), noWorkingDays);
         if (productionPlan != null)
        {
            Long result = new Long (productionPlan * 100 / (plannedMonthlyDemand.getNutriCapacity() + plannedMonthlyDemand.getPremiumCapacity()));
            result= Math.round((double)result);
            plannedMonthlyDemand.setUtilization(result);
        }
        else
        {
            plannedMonthlyDemand.setUtilization(new Long (-1));
        }
        
        //month map index: 0 - Jan, 11 - Dec
        String monthName = month.substring(0, month.length() - 5);
        int year = Integer.parseInt(month.substring(month.length() - 4));
        int monthIndex = -1;
        for (int i = 0; i < 12; ++i) {
            if (monthNameList[i].compareTo(monthName) == 0)
            {
                monthIndex = i;
            }
        }
        long saleForecast = saleForecastBeanLocal.getMonthlySaleForecasts(year, monthIndex, monthIndex).get(0).getTotalProductCaseQuantity();
        plannedMonthlyDemand.setMonthlyForecast(Long.toString(saleForecast));
        em.persist(plannedMonthlyDemand);
        return plannedMonthlyDemand;
    }
    
    public void updatePlannedMonthlyDemand(Long id, String monthlyForecast, Long productionPlan, Long inventory)
    {
        PlannedMonthlyDemand plannedMonthlyDemand = em.find(PlannedMonthlyDemand.class, id);
        plannedMonthlyDemand.setMonthlyForecast(monthlyForecast);
        plannedMonthlyDemand.setProductionPlan(productionPlan);
        plannedMonthlyDemand.setInventory(inventory);
        plannedMonthlyDemand.setWorkingHours(0);
        plannedMonthlyDemand.setOvertimeHours(0);
        //plannedMonthlyDemand.setNumberOfWorkingDays(workingDays);
        //plannedMonthlyDemand.setCapacity(capacity);
        plannedMonthlyDemand.setUtilization(new Long (productionPlan * 100 / (plannedMonthlyDemand.getNutriCapacity() + plannedMonthlyDemand.getPremiumCapacity())));
        em.persist(plannedMonthlyDemand);
        em.flush();
    }
    
    public boolean checkUtilization (Long productionPlan, Long capacity)
    {
        Double utilization = (Double) ((double) productionPlan / (double) capacity);
        if (utilization >= 0.9)
            return false;
        else
            return true;
    }
    
    public Long calculateInventory(Long salesForecast, Long productionPlan, Long previousInventory)
    {
        if (salesForecast == null || productionPlan == null || previousInventory == null)
        {
            return new Long(-1);
        }
        Long inventory = (productionPlan + previousInventory) - salesForecast;
        return inventory;
    }
    
    public List<PlannedMonthlyDemand> getPlannedMonthlyDemands() {
        Query q = em.createQuery("SELECT p FROM PlannedMonthlyDemand p");
        return (List<PlannedMonthlyDemand>) q.getResultList();
    }
    
    public PlannedMonthlyDemand findByMonth(String monthName) {
        Query q = em.createQuery("SELECT p FROM PlannedMonthlyDemand p WHERE p.monthName=:monthName");
        q.setParameter("monthName", monthName);
        //PlannedMonthlyDemand p = (PlannedMonthlyDemand) q.getSingleResult();
        //System.out.println(p.getMonthName());
        return (PlannedMonthlyDemand) q.getSingleResult();
    }

    public Long getWorkingDaysByMonth(String time) {
        String[] monthList = {"January", "February",
                          "March", "April", "May", "June", "July",
                          "August", "September", "October", "November",
                          "December"};
        String month = time.substring(0, time.length() - 5);
        int index = -1;
        for (int i = 0; i < 12; ++i) {
            if (month.compareTo(monthList[i]) == 0)
            {
                index = i;
                break;
            }
        }
        int year = Integer.parseInt(time.substring(time.length() - 4));
        
        Calendar c = Calendar.getInstance();
        if (index != -1)
        {
            c.set(year, index, 1);
        }
        else
        {
            System.out.println("CANNOT FIND THE MONTH");
        }
        int workingDaysCount = 0;
        while (index == c.get(Calendar.MONTH))
        {
            if (c.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && c.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY)
            {
                workingDaysCount ++;
            }
            c.add(Calendar.DAY_OF_MONTH, 1);
        }
        return new Long(workingDaysCount);   
    }
}

